import datetime
from collections import defaultdict
from typing import List, Dict

from pydantic import BaseModel, Field, root_validator


class OrderItemModel(BaseModel):
    spu_id: int = Field(..., description="商品spu_id", gt=1)
    sku_id: int = Field(..., description="商品sku_id", gt=1)
    quantity: int = Field(..., description="商品数量", gt=0)
    date: datetime.date = Field(None, description="预定日期")
    start_time: datetime.time = Field(None, description="预定开始时间")
    end_time: datetime.time = Field(None, description="预定结束时间")


class AddressInfoModel(BaseModel):
    address_id: int = Field(None, description="收件地址id,如果填了就用这个地址的信息")

    receive_phone: str = Field(None, description="收件人手机号", max_length=16)
    receive_name: str = Field(None, description="收件人姓名", max_length=128)
    province_id: int = Field(None, description="收件地址省份")
    province: str = Field(None, description="后端补充")
    city_id: int = Field(None, description="收件地址城市")
    city: str = Field(None, description="后端补充")
    area_id: int = Field(None, description="收件地址区")
    area: str = Field(None, description="后端补充")
    detail_address: str = Field(None, description="收件详细地址", max_length=128)

    @root_validator()
    def validate_root(cls, attrs):
        address_id: int = attrs.get("address_id")
        if address_id:
            return {"address_id": address_id}
        province_id = attrs.get("province_id")
        city_id = attrs.get("city_id")
        area_id = attrs.get("area_id")
        detail_address = attrs.get("detail_address")
        receive_phone = attrs.get("receive_phone")
        receive_name = attrs.get("receive_name")
        if not all([province_id, city_id, area_id, detail_address, receive_name, receive_phone]):
            raise ValueError("收件信息缺失")
        return {
            "province_id": province_id,
            "city_id": city_id,
            "area_id": area_id,
            "detail_address": detail_address,
            "receive_phone": receive_phone,
            "receive_name": receive_name
        }


class AddNewOrderModel(BaseModel):
    # 前端传的
    order_item_list: List[OrderItemModel] = Field(..., description="订单item列表")
    buyer_words: str = Field(None, description="买家备注")
    address_info: AddressInfoModel = Field(None, description="收件地址,如果是实物才有这个字段,虚拟商品是没有的")
    # 根据前端传递的解析出来的
    spu_id_to_sku_id_list: Dict[int, List[int]] = Field(None, description="spu id到sku id的映射")
    spu_id_list: List[int] = Field(None, description="spu id列表")
    sku_id_list: List[int] = Field(None, description="sku id列表")
    # 接口直接赋值
    precheck: bool = Field(None)

    @root_validator()
    def validate_root(cls, attrs: dict):
        order_item_list = attrs.get("order_item_list")
        exist = set()
        d = defaultdict(list)
        spu_id_list = []
        sku_id_list = []
        for each in order_item_list:
            k = f"{each.spu_id}_{each.sku_id}"
            if k in exist:
                raise ValueError("重复提交")
            spu_id_list.append(each.spu_id)
            sku_id_list.append(each.sku_id)
            d[each.spu_id].append(each.sku_id)
            exist.add(k)
        attrs["spu_id_to_sku_id_list"] = d
        attrs["spu_id_list"] = spu_id_list
        attrs["sku_id_list"] = sku_id_list
        return attrs

